package com.zhanhong.opencvdemo.presenter;

import android.app.Activity;
import android.content.CursorLoader;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.zhanhong.opencvdemo.config.AnswerSheetConfig;
import com.zhanhong.opencvdemo.config.RecognitionConfig;
import com.zhanhong.opencvdemo.model.AnswerSheetModel;
import com.zhanhong.opencvdemo.model.AnswerSheetModel.AnswerRowModel;
import com.zhanhong.opencvdemo.model.AnswerSheetModel.AnswerSheetItemModel;
import com.zhanhong.opencvdemo.model.OpenCVConfigBean;
import com.zhanhong.opencvdemo.utils.BitmapUtils;
import com.zhanhong.opencvdemo.utils.FileUtils;
import com.zhanhong.opencvdemo.utils.SpUtils;
import com.zhanhong.opencvdemo.utils.ThreadUtils;
import com.zhanhong.opencvdemo.value.CameraSetting;
import com.zhanhong.opencvdemo.value.FilePath;
import com.zhanhong.opencvdemo.value.IntentCode;
import com.zhanhong.opencvdemo.value.IntentKey;
import com.zhanhong.opencvdemo.view.CropActivity;
import com.zhanhong.opencvdemo.view.MainActivity;

import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDouble;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import static com.zhanhong.opencvdemo.value.IntentCode.GALLERY_REQUEST_CODE;

public class MainPresenterImpl implements MainPresenter {

    private final MainActivity mActivity;
    private OpenCVConfigBean mConfig = RecognitionConfig.getRecognitionParam(SpUtils.readString(SpUtils.SpType.KEY_RECOGNITION_CONFIG));
    private boolean mAllSingleChoice = SpUtils.readBoolean(SpUtils.SpType.KEY_SINGLE_CHOICE_QUESTION_ALL);
    private int mQuestionCount = SpUtils.readInt(SpUtils.SpType.KEY_QUESTION_COUNT) > 0 ? SpUtils.readInt(SpUtils.SpType.KEY_QUESTION_COUNT) : AnswerSheetConfig.QUESTION_TOTAL_COUNT;

    public MainPresenterImpl(MainActivity activity) {
        mActivity = activity;
    }

    public void refreshConfig() {
        mConfig = RecognitionConfig.getRecognitionParam(SpUtils.readString(SpUtils.SpType.KEY_RECOGNITION_CONFIG));
        mAllSingleChoice = SpUtils.readBoolean(SpUtils.SpType.KEY_SINGLE_CHOICE_QUESTION_ALL, true);
        mQuestionCount = SpUtils.readInt(SpUtils.SpType.KEY_QUESTION_COUNT) > 0 ? SpUtils.readInt(SpUtils.SpType.KEY_QUESTION_COUNT) : AnswerSheetConfig.QUESTION_TOTAL_COUNT;
    }

    public void initDirs() {
        FileUtils.createDir(FilePath.CACHE_DIR);
        FileUtils.createDir(FilePath.IMAGE_DIR);
        FileUtils.createDir(FilePath.LOG_DIR);
    }

    @Override
    public void initOpenCV() {
        OpenCVLoader.initDebug();
    }

    @Override
    public void handleActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case IntentCode.GALLERY_REQUEST_CODE:
                if (data != null) {
                    Uri uri = data.getData();
                    if (uri != null) {
                        String bitmapPath = getPicPathInGallery(uri);
                        if (!TextUtils.isEmpty(bitmapPath)) {
                            mActivity.onPhotoGetStart();
                            Bitmap sourceBitmap = BitmapUtils.loadBitmap(bitmapPath);
                            int sourceWidth = sourceBitmap.getWidth();
                            int sourceHeight = sourceBitmap.getHeight();
                            if (sourceWidth > CameraSetting.MIN_PICTURE_SIZE || sourceHeight > CameraSetting.MIN_PICTURE_SIZE) {
                                Bitmap resizeBitmap;
                                if (sourceWidth >= sourceHeight) {
                                    resizeBitmap = BitmapUtils.changeBitmapSize(sourceBitmap, CameraSetting.MIN_PICTURE_SIZE, (int) (1F * CameraSetting.MIN_PICTURE_SIZE / sourceWidth * sourceHeight));
                                } else {
                                    resizeBitmap = BitmapUtils.changeBitmapSize(sourceBitmap, (int) (1F * CameraSetting.MIN_PICTURE_SIZE / sourceHeight * sourceWidth), CameraSetting.MIN_PICTURE_SIZE);
                                }
                                File resizeFile = createImageFile();
                                BitmapUtils.save(resizeBitmap, resizeFile);
                                mActivity.onPhotoGetFinish(resizeFile);
                            } else {
                                mActivity.onPhotoGetFinish(new File(bitmapPath));
                            }

                        }
                    }
                }
                break;
            case IntentCode.CAMERA_REQUEST_CODE:
                if (resultCode == Activity.RESULT_OK && data != null) {
                    mActivity.onPhotoGetStart();
                    ThreadUtils.runOnSubThread(() -> {
                        byte[] bitmapBytes = data.getByteArrayExtra(IntentKey.KEY_PHOTO_IMAGE_BYTES);
                        File sourceFile = createImageFile();
                        if (bitmapBytes != null && bitmapBytes.length > 0) {
                            int camAngle = data.getIntExtra(IntentKey.KEY_PHOTO_IMAGE_ANGLE, 0);
                            Bitmap sourceBitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);
                            Bitmap rotatedBitmap = BitmapUtils.rotateImageView(camAngle, sourceBitmap);
                            BitmapUtils.save(rotatedBitmap, sourceFile);
                        }
                        ThreadUtils.runOnUIThread(() -> {
                            if (sourceFile.length() > 0) {
                                mActivity.onPhotoGetFinish(sourceFile);
                            } else {
                                sourceFile.delete();
                                mActivity.onPhotoGetFinish(null);
                            }
                        });
                    });
                }
                break;
            case IntentCode.CROP_REQUEST_CODE:
                if (resultCode == Activity.RESULT_OK && data != null) {
                    String cropPath = data.getStringExtra(IntentKey.KEY_CROP_PATH);
                    mActivity.onPhotoCrop(new File(cropPath));
                }
                break;
        }
    }

    @Override
    public void viewAlbum() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        mActivity.startActivityForResult(intent, GALLERY_REQUEST_CODE);
    }

    @Override
    public void cropPhoto(File file) {
        Intent intent = new Intent(mActivity, CropActivity.class);
        intent.putExtra(IntentKey.KEY_CROP_PATH, file.getAbsolutePath());
        mActivity.startActivityForResult(intent, IntentCode.CROP_REQUEST_CODE);
    }

    @Override
    public void dealWithPhoto(final File file) {

        refreshConfig();

        ThreadUtils.runOnSubThread(() -> {
            Bitmap srcBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());

            if (srcBitmap == null) {
                return;
            }

            Mat srcMat = new Mat();
            Utils.bitmapToMat(srcBitmap, srcMat);

            AnswerSheetModel answerSheet = new AnswerSheetModel(srcMat.width(), srcMat.height());

            //1灰度化
            Mat grayMat = doGray(srcBitmap, srcMat);

            //2模糊降噪
            Mat blurMat = doBlur(srcBitmap, grayMat);

            //3二值化
            Mat binaryMat = doBinary(srcBitmap, blurMat);

            //4绘制参考线
            Mat measureMat = doMeasure(srcBitmap, binaryMat, answerSheet);

            //5识别填涂位置
            checkAnswer(measureMat, answerSheet);

            srcMat.release();
            grayMat.release();
            blurMat.release();
            binaryMat.release();
            measureMat.release();
        });
    }

    private void checkAnswer(Mat preMat, AnswerSheetModel answerSheet) {
        final String stepName = "识别填涂位置";
        stepDealStart(stepName);
        try {
            for (int i = 0; i < answerSheet.answerRows.size(); i++) {
                AnswerRowModel answerRow = answerSheet.answerRows.get(i);
                for (int j = 0; j < answerRow.answers.size(); j++) {
                    AnswerSheetItemModel answerItem = answerRow.answers.get(j);
                    for (int k = 0; k < answerItem.points.length; k++) {
                        if (k % 2 == 0 && k < answerItem.points.length - 1) {
                            Point tlPoint = answerItem.points[k];
                            Point brPoint = answerItem.points[k + 1];
                            float offsetX = answerSheet.answerWidth * AnswerSheetConfig.OPTION_SHRINK_FACTOR;
                            float offsetY = answerSheet.answerHeight * AnswerSheetConfig.OPTION_SHRINK_FACTOR;
                            Point targetTlPoint = new Point(tlPoint.x + offsetX, tlPoint.y + offsetY);
                            Point targetBrPoint = new Point(brPoint.x - offsetX, brPoint.y - offsetY);
                            Mat roiMat = preMat.submat(new Rect(targetTlPoint, targetBrPoint));
                            MatOfDouble meanMat = new MatOfDouble();
                            MatOfDouble stdDevMat = new MatOfDouble();
                            double[] mean = new double[1];
                            double[] stdDev = new double[1];
                            Core.meanStdDev(roiMat, meanMat, stdDevMat);
                            meanMat.get(0, 0, mean);
                            stdDevMat.get(0, 0, stdDev);
                            float factor = formatDouble(mean[0]);
                            switch (k / 2) {
                                case 0:
                                    answerItem.factorA = factor;
                                    break;
                                case 1:
                                    answerItem.factorB = factor;
                                    break;
                                case 2:
                                    answerItem.factorC = factor;
                                    break;
                                case 3:
                                    answerItem.factorD = factor;
                                    break;
                            }
                            meanMat.release();
                            stdDevMat.release();
                            roiMat.release();
                        }
                    }
                }
            }
            List<AnswerSheetItemModel> answers = new ArrayList<>();
            List<Float> factors = new ArrayList<>();
            for (AnswerRowModel answerRow : answerSheet.answerRows) {
                for (AnswerSheetItemModel answer : answerRow.answers) {
                    factors.add(answer.factorA);
                    factors.add(answer.factorB);
                    factors.add(answer.factorC);
                    factors.add(answer.factorD);
                }
            }
            Collections.sort(factors);
            float maxFactor = factors.get(factors.size() - 1) > 255F * AnswerSheetConfig.LIMIT_ACCEPT_MAX_FACTOR ? 255F * AnswerSheetConfig.LIMIT_ACCEPT_MAX_FACTOR : factors.get(factors.size() - 1);
            float minFactor = factors.get(0);
            float limitMaxFactor = maxFactor * AnswerSheetConfig.LIMIT_ACCEPT_MAX_FACTOR * mConfig.limitAcceptMaxFactorRate;
            boolean limitMaxFactorIsValid = (maxFactor - minFactor) > 255F * AnswerSheetConfig.LIMIT_ACCEPT_MIN_FACTOR * mConfig.limitAcceptMaxFactorRate;
            for (AnswerRowModel answerRow : answerSheet.answerRows) {
                for (AnswerSheetItemModel answer : answerRow.answers) {
                    List<Float> questionFactors = new ArrayList<>();
                    questionFactors.add(answer.factorA);
                    questionFactors.add(answer.factorB);
                    questionFactors.add(answer.factorC);
                    questionFactors.add(answer.factorD);
                    Collections.sort(questionFactors);
                    float questionMaxFactor = questionFactors.get(questionFactors.size() - 1);
                    if (mAllSingleChoice) {
                        answer.checkA = answer.factorA == questionMaxFactor && answer.factorA > limitMaxFactor && limitMaxFactorIsValid;
                        answer.checkB = answer.factorB == questionMaxFactor && answer.factorB > limitMaxFactor && limitMaxFactorIsValid;
                        answer.checkC = answer.factorC == questionMaxFactor && answer.factorC > limitMaxFactor && limitMaxFactorIsValid;
                        answer.checkD = answer.factorD == questionMaxFactor && answer.factorD > limitMaxFactor && limitMaxFactorIsValid;
                        if (!answer.checkA && !answer.checkB && !answer.checkC && !answer.checkD) {
                            float totalFactors = answer.factorA + answer.factorB + answer.factorC + answer.factorD;
                            answer.checkA = answer.factorA == questionMaxFactor && answer.factorA > totalFactors * AnswerSheetConfig.LIMIT_ACCEPT_TOTAL_PERCENT_FACTOR * mConfig.limitAcceptMaxFactorRate && answer.factorA > maxFactor * AnswerSheetConfig.LIMIT_RECHECK_MIN_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                            answer.checkB = answer.factorB == questionMaxFactor && answer.factorB > totalFactors * AnswerSheetConfig.LIMIT_ACCEPT_TOTAL_PERCENT_FACTOR * mConfig.limitAcceptMaxFactorRate && answer.factorB > maxFactor * AnswerSheetConfig.LIMIT_RECHECK_MIN_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                            answer.checkC = answer.factorC == questionMaxFactor && answer.factorC > totalFactors * AnswerSheetConfig.LIMIT_ACCEPT_TOTAL_PERCENT_FACTOR * mConfig.limitAcceptMaxFactorRate && answer.factorC > maxFactor * AnswerSheetConfig.LIMIT_RECHECK_MIN_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                            answer.checkD = answer.factorD == questionMaxFactor && answer.factorD > totalFactors * AnswerSheetConfig.LIMIT_ACCEPT_TOTAL_PERCENT_FACTOR * mConfig.limitAcceptMaxFactorRate && answer.factorD > maxFactor * AnswerSheetConfig.LIMIT_RECHECK_MIN_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                        }
                    } else {
                        answer.checkA = answer.factorA > limitMaxFactor && answer.factorA > questionMaxFactor * AnswerSheetConfig.LIMIT_ACCEPT_MAX_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                        answer.checkB = answer.factorB > limitMaxFactor && answer.factorB > questionMaxFactor * AnswerSheetConfig.LIMIT_ACCEPT_MAX_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                        answer.checkC = answer.factorC > limitMaxFactor && answer.factorC > questionMaxFactor * AnswerSheetConfig.LIMIT_ACCEPT_MAX_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                        answer.checkD = answer.factorD > limitMaxFactor && answer.factorD > questionMaxFactor * AnswerSheetConfig.LIMIT_ACCEPT_MAX_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                        if (!answer.checkA && !answer.checkB && !answer.checkC && !answer.checkD) {
                            float totalFactors = answer.factorA + answer.factorB + answer.factorC + answer.factorD;
                            answer.checkA = answer.factorA > totalFactors * AnswerSheetConfig.LIMIT_ACCEPT_TOTAL_PERCENT_FACTOR * mConfig.limitAcceptMaxFactorRate && answer.factorA > maxFactor * AnswerSheetConfig.LIMIT_RECHECK_MIN_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                            answer.checkB = answer.factorB > totalFactors * AnswerSheetConfig.LIMIT_ACCEPT_TOTAL_PERCENT_FACTOR * mConfig.limitAcceptMaxFactorRate && answer.factorB > maxFactor * AnswerSheetConfig.LIMIT_RECHECK_MIN_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                            answer.checkC = answer.factorC > totalFactors * AnswerSheetConfig.LIMIT_ACCEPT_TOTAL_PERCENT_FACTOR * mConfig.limitAcceptMaxFactorRate && answer.factorC > maxFactor * AnswerSheetConfig.LIMIT_RECHECK_MIN_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                            answer.checkD = answer.factorD > totalFactors * AnswerSheetConfig.LIMIT_ACCEPT_TOTAL_PERCENT_FACTOR * mConfig.limitAcceptMaxFactorRate && answer.factorD > maxFactor * AnswerSheetConfig.LIMIT_RECHECK_MIN_FACTOR * mConfig.limitAcceptMaxFactorRate && limitMaxFactorIsValid;
                        }
                    }
                    answers.add(answer);
                }
            }
            List<AnswerSheetItemModel> subAnswers = answers.subList(0, mQuestionCount);
            stepDealComplete(stepName, subAnswers, true);
        } catch (Exception e) {
            stepDealComplete(stepName + "失败：" + e.getMessage(), null, false);
        }
    }

    @NonNull
    private Mat doMeasure(Bitmap srcBitmap, Mat preMat, AnswerSheetModel answerSheet) {
        final String stepName = "内容分析";
        stepDealStart(stepName);
        final Bitmap measureBitmap = createBitmapAsSrc(srcBitmap);
        Mat measureMat = preMat.clone();
        try {
            calcReferenceAxis(measureMat, answerSheet);
            Utils.matToBitmap(measureMat, measureBitmap);
            BitmapUtils.save(measureBitmap, new File(FilePath.CACHE_DIR, "MainMeasureBitmap.png"));
            stepDealComplete(stepName, null, true);
        } catch (Exception e) {
            measureMat.release();
            stepDealComplete(stepName + "失败：" + e.getMessage(), null, false);
        }
        return measureMat;
    }

    @NonNull
    private Mat doBinary(Bitmap srcBitmap, Mat preMat) {
        final String stepName = "二值化";
        stepDealStart(stepName);
        final Bitmap binaryBitmap = createBitmapAsSrc(srcBitmap);
        Mat binaryMat = new Mat();
        try {
            Imgproc.adaptiveThreshold(preMat, binaryMat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, mConfig.binaryBlockSize, mConfig.binaryC);
            Utils.matToBitmap(binaryMat, binaryBitmap);
            BitmapUtils.save(binaryBitmap, new File(FilePath.CACHE_DIR, "MainBinaryBitmap.png"));
            stepDealComplete(stepName, null, true);
        } catch (Exception e) {
            binaryMat.release();
            stepDealComplete(stepName + "失败：" + e.getMessage(), null, false);
        }
        return binaryMat;
    }

    @NonNull
    private Mat doBlur(Bitmap srcBitmap, Mat preMat) {
        final String stepName = "高斯模糊降噪";
        stepDealStart(stepName);
        final Bitmap blurBitmap = createBitmapAsSrc(srcBitmap);
        Mat blurMat = new Mat();
        try {
            Imgproc.GaussianBlur(preMat, blurMat, new Size(mConfig.blurSize, mConfig.blurSize), 0);
            Utils.matToBitmap(blurMat, blurBitmap);
            BitmapUtils.save(blurBitmap, new File(FilePath.CACHE_DIR, "MainBlurBitmap.png"));
            stepDealComplete(stepName, null, true);
        } catch (Exception e) {
            blurMat.release();
            stepDealComplete(stepName + "失败：" + e.getMessage(), null, false);
        }
        return blurMat;
    }

    @NonNull
    private Mat doGray(Bitmap srcBitmap, Mat preMat) {
        final String stepName = "灰度化";
        stepDealStart(stepName);
        final Bitmap grayBitmap = createBitmapAsSrc(srcBitmap);
        Mat grayMat = new Mat();
        try {
            Imgproc.cvtColor(preMat, grayMat, Imgproc.COLOR_BGRA2GRAY);
            Utils.matToBitmap(grayMat, grayBitmap);
            BitmapUtils.save(grayBitmap, new File(FilePath.CACHE_DIR, "MainGrayBitmap.png"));
            stepDealComplete(stepName, null, true);
        } catch (Exception e) {
            grayMat.release();
            stepDealComplete(stepName + "失败：" + e.getMessage(), null, false);
        }
        return grayMat;
    }

    private void calcReferenceAxis(Mat measureMat, AnswerSheetModel answerSheet) {
        //绘制横向直线
        Imgproc.line(measureMat, new Point(0, answerSheet.offsetTop), new Point(answerSheet.width, answerSheet.offsetTop), getLineColorWhite());
        Imgproc.line(measureMat, new Point(0, answerSheet.height - answerSheet.offsetBottom), new Point(answerSheet.width, answerSheet.height - answerSheet.offsetBottom), getLineColorWhite());
        for (int i = 1; i <= AnswerSheetConfig.TOTAL_ROW_COUNT; i++) {
            int preEmptyRowCount = i / AnswerSheetConfig.PER_ROW_COUNT;
            float marginTop = answerSheet.offsetTop + i * answerSheet.answerHeight + preEmptyRowCount * answerSheet.emptyRowHeight;
            //最后一条线不需要在循环中绘制，之前已经绘制过
            if (i < AnswerSheetConfig.TOTAL_ROW_COUNT) {
                if (i % AnswerSheetConfig.PER_ROW_COUNT == 0) {
                    Imgproc.line(measureMat, new Point(0, marginTop - answerSheet.emptyRowHeight), new Point(answerSheet.width, marginTop - answerSheet.emptyRowHeight), getLineColorWhite());
                }
                Imgproc.line(measureMat, new Point(0, marginTop), new Point(answerSheet.width, marginTop), getLineColorWhite());
            }
        }
        //绘制纵向直线
        Imgproc.line(measureMat, new Point(answerSheet.offsetLeft, 0), new Point(answerSheet.offsetLeft, answerSheet.height), getLineColorWhite());
        Imgproc.line(measureMat, new Point(answerSheet.width - answerSheet.offsetRight, 0), new Point(answerSheet.width - answerSheet.offsetRight, answerSheet.height), getLineColorWhite());
        for (int i = 1; i <= AnswerSheetConfig.TOTAL_COL_COUNT; i++) {
            int preEmptyColCount = i / AnswerSheetConfig.PER_COL_COUNT;
            float marginLeft = answerSheet.offsetLeft + i * answerSheet.answerWidth + preEmptyColCount * answerSheet.emptyColWidth;

            //最后一条线不需要在循环中绘制，之前已经绘制过
            if (i < AnswerSheetConfig.TOTAL_COL_COUNT) {
                if (i % AnswerSheetConfig.PER_COL_COUNT == 0) {
                    Imgproc.line(measureMat, new Point(marginLeft - answerSheet.emptyColWidth, 0), new Point(marginLeft - answerSheet.emptyColWidth, answerSheet.height), getLineColorWhite());
                }
                Imgproc.line(measureMat, new Point(marginLeft, 0), new Point(marginLeft, answerSheet.height), getLineColorWhite());
            }
        }
    }

    public float formatDouble(double value) {
        return (float) Math.round(value * 100) / 100;
    }

    @NonNull
    private Scalar getLineColorWhite() {
        return new Scalar(255, 255, 255);
    }

    private Bitmap createBitmapAsSrc(Bitmap srcBitmap) {
        return Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
    }

    private void stepDealComplete(final String stepName, final List<AnswerSheetItemModel> answers, final boolean success) {
        ThreadUtils.runOnUIThread(() -> mActivity.onPhotoDealFinish(answers, stepName, success));
    }

    private void stepDealStart(final String stepName) {
        ThreadUtils.runOnUIThread(() -> mActivity.onPhotoDealStart(stepName));
    }

    private File createImageFile() {
        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA).format(new Date().getTime());
        String imageFileName = "IMG" + timeStamp;
        return new File(FilePath.IMAGE_DIR + File.separator + imageFileName + ".png");
    }

    private String getPicPathInGallery(Uri uri) {
        String path = "";
        if (!TextUtils.isEmpty(uri.getAuthority())) {
            //Android多媒体数据库的封装接口，具体的看Android文档
            Cursor cursor;
            CursorLoader cursorLoader = new CursorLoader(mActivity, uri, null, null, null, null);
            cursor = cursorLoader.loadInBackground();
            if (cursor != null) {
                //获得用户选择的图片的索引值
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                //将光标移至开头，这个很重要，不小心很容易引起越界
                cursor.moveToFirst();
                //最后根据索引值获取图片路径
                path = cursor.getString(column_index);
            }
        } else {
            path = uri.getPath();
        }
        return path;
    }

}